﻿#include "spectrum.h"
#include "math.h"
#include <QDebug>

#define IPP_PI    ( 3.14159265358979323846 )  /* ANSI C does not support M_PI */
#define IPP_2PI   ( 6.28318530717958647692 )  /* 2*pi                         */
#define IPP_PI2   ( 1.57079632679489661923 )  /* pi/2                         */
#define IPP_PI4   ( 0.78539816339744830961 )  /* pi/4                         */
#define IPP_PI180 ( 0.01745329251994329577 )  /* pi/180                       */
#define IPP_RPI   ( 0.31830988618379067154 )  /* 1/pi                         */


//template <typename Type>
//Type IO(Type alpha){
//    double J = 1.0,
//            K = alpha / 2.0,
//            iOld = 1.0,
//            iNew;
//    bool converge = false;
//    for(int i=1;i<MAXTERM;++i){
//        J *= K/i;
//        iNew = iOld + J*J;
//        if((iNew - iOld) < EPS){
//            converge = true;
//            break;
//        }
//    }
//    if(!converge) return Type(0);
//    return Type(iNew);
//}

//矩形窗
void yanlei_wind_none_f32(float *window,int len)
{
    for(int i = 0; i < len/2; i++){
        window[i] = 1;
        window[len -1 - i] = window[i];
    }
}


//矩形窗
void yanlei_wind_rectangle_f32(float *window,int len)
{
    for(int i = 0; i < len/2; i++){
        window[i] = i/(len/4);
        window[len -1 - i] = window[i];
    }
}

//三角形窗
void yanlei_wind_bartlett_f32(float *window,int len)
{
    float len_mult = 1/(float)(len - 1);
    for(int i = 0; i < len/2; i++){
        window[i] = i * 2 * len_mult;
        window[len -1 - i] = window[i];
    }
}

//汉宁窗
void yanlei_wind_hanning_f32(float *window,int len)
{
    const float a0 = 0.5;
    const float a1 = 0.5;

    float len_mult = 1/(float)(len - 1);
    for(int i = 0; i < len/2; i++){
        window[i] =
                a0
                - a1 * cosf(i * IPP_2PI * len_mult);
        window[len -1 - i] = window[i];
    }
}
//海明窗
void yanlei_wind_hamming_f32(float *window,int len)
{
    const float a0 = 0.54;
    const float a1 = 0.46;

    float len_mult = 1/(float)(len - 1);
    for(int i = 0; i < len/2; i++){
        window[i] =
                a0
                - a1 * cosf(i * IPP_2PI * len_mult);
        window[len -1 - i] = window[i];
    }
}
//布莱克曼窗
void yanlei_wind_blackman_f32(float *window,int len)
{
    const float a0 = 0.42;
    const float a1 = 0.5;
    const float a2 = 0.08;

    float len_mult = 1/(float)(len - 1);
    for(int i = 0; i < len/2; i++){
        window[i] =
                a0
                - a1 * cosf(i * IPP_2PI * len_mult)
                + a2 * cosf(i * 2 * IPP_2PI * len_mult);
        window[len -1 - i] = window[i];
    }
}
//布莱克曼-哈里斯窗
void yanlei_wind_backman_harris_f32(float *window,int len){
    const float a0 = 0.35875;
    const float a1 = 0.48829;
    const float a2 = 0.14128;
    const float a3 = 0.01168;

    float len_mult = 1/(float)(len - 1);
    for(int i = 0; i < len/2; i++){
        window[i] =
                a0
                - a1 * cosf(i * IPP_2PI * len_mult)
                + a2 * cosf(i * 2 * IPP_2PI * len_mult)
                - a3 * cosf(i * 3 * IPP_2PI * len_mult);
        window[len -1 - i] = window[i];
    }
}

//布莱克曼-纳托儿窗
void yanlei_wind_backman_nuttall_f32(float *window,int len){
    const float a0 = 0.3635819;
    const float a1 = 0.4891775;
    const float a2 = 0.1365995;
    const float a3 = 0.0106411;

    float len_mult = 1/(float)(len - 1);
    for(int i = 0; i < len/2; i++){
        window[i] =
                a0
                - a1 * cosf(i * IPP_2PI * len_mult)
                + a2 * cosf(i * 2 * IPP_2PI * len_mult)
                - a3 * cosf(i * 3 * IPP_2PI * len_mult);
        window[len -1 - i] = window[i];
    }
}

//凯赛-贝塞尔窗
void yanlei_wind_kaiser_basel_f32(float *window, int len,float alpha ) {
    // 计算 beta 参数
    float beta = alpha * IPP_PI;

    // 初始化中间变量
    float tem;
    float arg;

    // 遍历整个窗口长度
    for (int i = 0; i < len; i++) {
        // 计算中间变量 tem
        tem = sqrtf((float)i * (len - i - 1.0f)) / (len - 1.0f);

        // 计算凯赛-贝塞尔窗函数值
        arg = beta * tem;
        window[i] = expf(-0.5f * arg * arg);
    }
}
//高斯窗
void yanlei_wind_gaussian_f32(float *window,int len)
{
    float alpha = 2.5;
    float center = (len-1) / (float)2 ;
    for(int i = 0; i < len/2; i++){
        float tem = alpha * (i - center) / center;
        window[i] = exp(-0.5 * tem * tem);
        window[len -1 - i] = window[i];
    }
}

//平顶窗
void yanlei_wind_flat_top_f32(float *window,int len){
    const float a0 = 0.21557895;
    const float a1 = 0.41663158;
    const float a2 = 0.277263158;
    const float a3 = 0.082578947;
    const float a4 = 0.006947368;

    float len_mult = 1/(float)(len - 1);
    for(int i = 0; i < len/2; i++){
        window[i] =
                a0
                - a1 * cosf(i * IPP_2PI * len_mult)
                + a2 * cosf(i * 2 * IPP_2PI * len_mult)
                - a3 * cosf(i * 3 * IPP_2PI * len_mult)
                + a4 * cosf(i * 4 * IPP_2PI * len_mult);
        window[len -1 - i] = window[i];
    }
}
//纳托儿窗
void yanlei_wind_nuttall_f32(float *window,int len){
    const float a0 = 0.355768;
    const float a1 = 0.487396;
    const float a2 = 0.144232;
    const float a3 = 0.012604;

    float len_mult = 1/(float)(len - 1);
    for(int i = 0; i < len/2; i++){
        window[i] =
                a0
                - a1 * cosf(i * IPP_2PI * len_mult)
                + a2 * cosf(i * 2 * IPP_2PI * len_mult)
                - a3 * cosf(i * 3 * IPP_2PI * len_mult);
        window[len -1 - i] = window[i];
    }
}

// 切比雪夫窗
void yanlei_wind_chebyshev_f32(float *window, int len) {
    for (int n = 0; n < len; n++) {
        // 计算切比雪夫窗函数值
        float arg = (float)(2 * n + 1) / (2 * len);
        float value = cos(IPP_PI * arg);

        // 存储到窗口数组中
        window[n] = value;
    }
}

Spectrum::Spectrum(int outFftLen,int m_winType, int type)
{
    fftLen = outFftLen;
    workLen = outFftLen * 2;
    disposeType = type;

    winBuf = new float[workLen];
    fOutBuf = new float[fftLen];

    setWinType(m_winType);

    if(disposeType == R2FFT){
        rInBuf = (float *)fftwf_malloc(sizeof(float) * workLen);
        cOutBuf =(fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex) * workLen);
        real_plan = fftwf_plan_dft_r2c_1d(workLen, rInBuf, cOutBuf, FFTW_ESTIMATE);
    }else{
        cInBuf = (fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex) * fftLen);
        cOutBuf =(fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex) * fftLen);
        real_plan = fftwf_plan_dft_1d(fftLen, cInBuf,cOutBuf,FFTW_FORWARD, FFTW_ESTIMATE);
    }
}

void Spectrum::setWinType(int m_winType)
{
    winType = m_winType;

    if(winType == WIN_None){
        yanlei_wind_none_f32(winBuf,disposeType == R2FFT ? workLen : fftLen);
    }else if(winType == WIN_Rectangle){
        yanlei_wind_rectangle_f32(winBuf,disposeType == R2FFT ? workLen : fftLen);
    }else if(winType == WIN_Bartlett){
        yanlei_wind_bartlett_f32(winBuf,disposeType == R2FFT ? workLen : fftLen);
    }else if(winType == WIN_Hanning){
        yanlei_wind_hanning_f32(winBuf,disposeType == R2FFT ? workLen : fftLen);
    }else if(winType == WIN_Hamming){
        yanlei_wind_hamming_f32(winBuf,disposeType == R2FFT ? workLen : fftLen);
    }else if(winType == WIN_Blackman){
        yanlei_wind_blackman_f32(winBuf,disposeType == R2FFT ? workLen : fftLen);
    }else if(winType == WIN_BlackmanHarris){
        yanlei_wind_backman_harris_f32(winBuf,disposeType == R2FFT ? workLen : fftLen);
    }else if(winType == WIN_BlackmanNuttall){
        yanlei_wind_backman_nuttall_f32(winBuf,disposeType == R2FFT ? workLen : fftLen);
    }else if(winType == WIN_Gaussian){
        yanlei_wind_gaussian_f32(winBuf,disposeType == R2FFT ? workLen : fftLen);
    }else if(winType == WIN_FlatTop){
        yanlei_wind_flat_top_f32(winBuf,disposeType == R2FFT ? workLen : fftLen);
    }else if(winType == WIN_Nuttall){
        yanlei_wind_nuttall_f32(winBuf,disposeType == R2FFT ? workLen : fftLen);
    }else if(winType == WIN_KaiserBasel){
        yanlei_wind_none_f32(winBuf,disposeType == R2FFT ? workLen : fftLen);
    }else if(winType == WIN_Chebyshev){
        yanlei_wind_none_f32(winBuf,disposeType == R2FFT ? workLen : fftLen);
    }else{
        yanlei_wind_none_f32(winBuf,disposeType == R2FFT ? workLen : fftLen);
    }
}

void Spectrum::getWindow(short value, short outBuf[])
{
    for(int i=0;i<fftLen;i++)
        outBuf[i] = value * winBuf[i];
}

Spectrum::~Spectrum(){
    delete  []winBuf;
    delete []fOutBuf;

    if(disposeType == R2FFT){
        fftwf_free(rInBuf);
        fftwf_free(cOutBuf);
    }else if(disposeType == C2FFT){
        fftwf_free(cInBuf);
        fftwf_free(cOutBuf);
    }
    fftwf_destroy_plan(real_plan);
}

void Spectrum::ConversionMAX(short inBuf[], int inLen, float outBuf[],float levelPoor, bool smooth, int smoothNum)
{
    bool frist = true;
    if(disposeType == R2FFT){
        for(int v = 0;v < inLen / workLen;v++){//先将short输入转为float
            for(int i=0;i<workLen;i++){
                rInBuf[i]=float(inBuf[(workLen*v) + i]*winBuf[i]);
            }
            fftwf_execute(real_plan);
            if(frist){
                for(int i=1;i<fftLen+1;++i)
                    outBuf[i-1] = log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor;
                frist = false;
            }else{//累积
                for(int i=1;i<fftLen+1;i++)
                    outBuf[i-1] = outBuf[i] > log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor ?
                                outBuf[i] : log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor;
            }
        }
    }else if(disposeType == C2FFT){
        for(int v = 0;v < inLen / workLen;v++){
            for(int i=0;i<fftLen;++i){
                cInBuf[i][0]=float(inBuf[i*2+workLen*v]*winBuf[i]);
                cInBuf[i][1]=float(inBuf[i*2+1+workLen*v]*winBuf[i]);
            }
            fftwf_execute(real_plan);
            int halfLen = fftLen/2;
            if(frist){
                for(int i=0;i<halfLen;i++)
                    outBuf[i] = log10f(sqrtf(cOutBuf[i+halfLen][0]*cOutBuf[i+halfLen][0]+cOutBuf[i+halfLen][1]*cOutBuf[i+halfLen][1]))*20.0f + levelPoor;   //I
                for(int i=0;i<halfLen;i++)
                    outBuf[i+halfLen] = log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f+ levelPoor; //Q
                frist = false;
            }else{  //累积
                for(int i=0;i<fftLen/2;i++)
                    outBuf[i] = outBuf[i] > log10f(sqrtf(cOutBuf[i+halfLen][0]*cOutBuf[i+halfLen][0]+cOutBuf[i+halfLen][1]*cOutBuf[i+halfLen][1]))*20.0f + levelPoor ?
                                outBuf[i] : log10f(sqrtf(cOutBuf[i+halfLen][0]*cOutBuf[i+halfLen][0]+cOutBuf[i+halfLen][1]*cOutBuf[i+halfLen][1]))*20.0f + levelPoor;
                for(int i=0;i<fftLen/2;i++)
                    outBuf[i+fftLen/2] = outBuf[i+fftLen/2] > log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor ?
                                outBuf[i+fftLen/2] : log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor;
            }
        }
    }
    if(smooth){
        for(int j=0;j<smoothNum;j++){
            for(int i=1;i<fftLen-1;i++)
                outBuf[i]=(outBuf[i]+outBuf[i-1]*0.5f+outBuf[i+1]*0.5f)/2.0f;
            outBuf[0] =  outBuf[1];
            outBuf[fftLen-1] = outBuf[fftLen-2];
        }
    }
}

void Spectrum::ConversionMEAN(short inBuf[],int inLen, float outBuf[],float levelPoor,bool smooth,int smoothNum)
{
    int meanNum =  inLen / fftLen; //平均次数
    double meanFactor = 1.0 / meanNum; //比例因子
    memset((char*)fOutBuf,0,fftLen*sizeof (float));

    if(disposeType == R2FFT){
        for(int v = 0;v < inLen / workLen;v++){//先将short输入转为float
            for(int i=0;i<workLen;i++){
                rInBuf[i]=float(inBuf[i+(workLen*v)]*winBuf[i]);
            }
            fftwf_execute(real_plan);
            for(int i=0;i<fftLen;i++)
                fOutBuf[i] += (log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor) * meanFactor;
        }
    }else if(disposeType == C2FFT){
        for(int v = 0;v < inLen / fftLen;v++){
            for(int i=0;i<fftLen;i+=2){
                cInBuf[i/2][0]=float(inBuf[i+fftLen*v]*winBuf[i]);
                cInBuf[i/2][1]=float(inBuf[i+1+fftLen*v]*winBuf[i]);
            }
            fftwf_execute(real_plan);
            int halfLen = fftLen/2;
            for(int i=0;i<fftLen/2;i++)
                fOutBuf[i] = (log10f(sqrtf(cOutBuf[i+halfLen][0]*cOutBuf[i+halfLen][0]+cOutBuf[i+halfLen][1]*cOutBuf[i+halfLen][1]))*20.0f + levelPoor) * meanFactor;
            for(int i=0;i<fftLen/2;i++)
                fOutBuf[i+fftLen/2] = (log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor) * meanFactor;
        }
    }
    for(int i=0;i<fftLen;i++) // float 2 short
        outBuf[i] = fOutBuf[i];
    if(smooth){
        for(int j=0;j<smoothNum;j++)
            for(int i=1;i<fftLen;i++)
                outBuf[i]=(outBuf[i]+outBuf[i-1]*0.5+outBuf[i+1]*0.5)/2.0;
    }
}

void Spectrum::ConversionMIN(short inBuf[], int inLen, float outBuf[], float levelPoor,bool smooth, int smoothNum)
{
    bool frist = true;
    if(disposeType == R2FFT){
        for(int v = 0;v < inLen / workLen;v++){//先将short输入转为float
            for(int i=0;i<workLen;i++){
                rInBuf[i]=float(inBuf[i+(workLen*v)]*winBuf[i]);
            }
            fftwf_execute(real_plan);
            if(frist){
                for(int i=1;i<fftLen+1;i++)
                    outBuf[i-1] = log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor;
                frist = false;
            }else{//累积
                for(int i=1;i<fftLen+1;i++)
                    outBuf[i-1] = outBuf[i] < log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor ?
                                outBuf[i] : log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor;
            }
        }
    }else if(disposeType == C2FFT){
        for(int v = 0;v < inLen / workLen;v++){
            for(int i=0;i<fftLen;++i){
                cInBuf[i][0]=float(inBuf[i*2+workLen*v]*winBuf[i]);
                cInBuf[i][1]=float(inBuf[i*2+1+workLen*v]*winBuf[i]);
            }
            fftwf_execute(real_plan);
            int halfLen = fftLen/2;
            if(frist){
                for(int i=0;i<halfLen;i++)
                    outBuf[i] = log10f(sqrtf(cOutBuf[i+halfLen][0]*cOutBuf[i+halfLen][0]+cOutBuf[i+halfLen][1]*cOutBuf[i+halfLen][1]))*20.0f + levelPoor;   //I
                for(int i=0;i<halfLen;i++)
                    outBuf[i+halfLen] = log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f+ levelPoor; //Q
                frist = false;
            }else{  //累积
                for(int i=0;i<fftLen/2;i++)
                    outBuf[i] = outBuf[i] < log10f(sqrtf(cOutBuf[i+halfLen][0]*cOutBuf[i+halfLen][0]+cOutBuf[i+halfLen][1]*cOutBuf[i+halfLen][1]))*20.0f + levelPoor ?
                                outBuf[i] : log10f(sqrtf(cOutBuf[i+halfLen][0]*cOutBuf[i+halfLen][0]+cOutBuf[i+halfLen][1]*cOutBuf[i+halfLen][1]))*20.0f + levelPoor;
                for(int i=0;i<fftLen/2;i++)
                    outBuf[i+fftLen/2] = outBuf[i+fftLen/2] < log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor ?
                                outBuf[i+fftLen/2] : log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor;
            }
        }
    }
    if(smooth){
        for(int j=0;j<smoothNum;j++)
            for(int i=1;i<fftLen;i++)
                outBuf[i]=(outBuf[i]+outBuf[i-1]*0.5+outBuf[i+1]*0.5)/2.0;
    }
}

void Spectrum::ConversionMAX(short inBuf[], int inLen, short outBuf[],short levelPoor, bool smooth, int smoothNum)
{
    bool frist = true;
    if(disposeType == R2FFT){
        for(int v = 0;v < inLen / workLen;v++){//先将short输入转为float
            for(int i=0;i<workLen;i++){
                rInBuf[i]=float(inBuf[(workLen*v) + i]*winBuf[i]);
            }
            fftwf_execute(real_plan);
            if(frist){
                for(int i=1;i<fftLen+1;++i)
                    outBuf[i-1] = log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor;
                frist = false;
            }else{//累积
                for(int i=1;i<fftLen+1;i++)
                    outBuf[i-1] = outBuf[i] > log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor ?
                                outBuf[i] : log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor;
            }
        }
    }else if(disposeType == C2FFT){
        for(int v = 0;v < inLen / workLen;v++){
            for(int i=0;i<fftLen;++i){
                cInBuf[i][0]=float(inBuf[i*2+workLen*v]*winBuf[i]);
                cInBuf[i][1]=float(inBuf[i*2+1+workLen*v]*winBuf[i]);
            }
            fftwf_execute(real_plan);
            int halfLen = fftLen/2;
            if(frist){
                for(int i=0;i<halfLen;i++)
                    outBuf[i] = log10f(sqrtf(cOutBuf[i+halfLen][0]*cOutBuf[i+halfLen][0]+cOutBuf[i+halfLen][1]*cOutBuf[i+halfLen][1]))*20.0f + levelPoor;   //I
                for(int i=0;i<halfLen;i++)
                    outBuf[i+halfLen] = log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f+ levelPoor; //Q
                frist = false;
            }else{  //累积
                for(int i=0;i<fftLen/2;i++)
                    outBuf[i] = outBuf[i] > log10f(sqrtf(cOutBuf[i+halfLen][0]*cOutBuf[i+halfLen][0]+cOutBuf[i+halfLen][1]*cOutBuf[i+halfLen][1]))*20.0f + levelPoor ?
                                outBuf[i] : log10f(sqrtf(cOutBuf[i+halfLen][0]*cOutBuf[i+halfLen][0]+cOutBuf[i+halfLen][1]*cOutBuf[i+halfLen][1]))*20.0f + levelPoor;
                for(int i=0;i<fftLen/2;i++)
                    outBuf[i+fftLen/2] = outBuf[i+fftLen/2] > log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor ?
                                outBuf[i+fftLen/2] : log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor;
            }
        }
    }
    if(smooth){
        for(int j=0;j<smoothNum;j++){
            for(int i=1;i<fftLen-1;i++)
                outBuf[i]=(outBuf[i]+outBuf[i-1]*0.5f+outBuf[i+1]*0.5f)/2.0f;
            outBuf[0] =  outBuf[1];
            outBuf[fftLen-1] = outBuf[fftLen-2];
        }
    }
}

void Spectrum::ConversionMEAN(short inBuf[], int inLen, short outBuf[],short levelPoor,bool smooth,int smoothNum)
{
    int meanNum =  inLen / fftLen; //平均次数
    double meanFactor = 1.0 / meanNum; //比例因子
    memset((char*)fOutBuf,0,fftLen*sizeof (float));

    if(disposeType == R2FFT){
        for(int v = 0;v < inLen / workLen;v++){//先将short输入转为float
            for(int i=0;i<workLen;i++){
                rInBuf[i]=float(inBuf[i+(workLen*v)]*winBuf[i]);
            }
            fftwf_execute(real_plan);
            for(int i=0;i<fftLen;i++)
                fOutBuf[i] += (log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor) * meanFactor;
        }
    }else if(disposeType == C2FFT){
        for(int v = 0;v < inLen / fftLen;v++){
            for(int i=0;i<fftLen;i+=2){
                cInBuf[i/2][0]=float(inBuf[i+fftLen*v]*winBuf[i]);
                cInBuf[i/2][1]=float(inBuf[i+1+fftLen*v]*winBuf[i]);
            }
            fftwf_execute(real_plan);
            int halfLen = fftLen/2;
            for(int i=0;i<fftLen/2;i++)
                fOutBuf[i] = (log10f(sqrtf(cOutBuf[i+halfLen][0]*cOutBuf[i+halfLen][0]+cOutBuf[i+halfLen][1]*cOutBuf[i+halfLen][1]))*20.0f + levelPoor) * meanFactor;
            for(int i=0;i<fftLen/2;i++)
                fOutBuf[i+fftLen/2] = (log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor) * meanFactor;
        }
    }
    for(int i=0;i<fftLen;i++) // float 2 short
        outBuf[i] = fOutBuf[i];
    if(smooth){
        for(int j=0;j<smoothNum;j++)
            for(int i=1;i<fftLen;i++)
                outBuf[i]=(outBuf[i]+outBuf[i-1]*0.5+outBuf[i+1]*0.5)/2.0;
    }
}

void Spectrum::ConversionMIN(short inBuf[], int inLen, short outBuf[], short levelPoor,bool smooth, int smoothNum)
{
    bool frist = true;
    if(disposeType == R2FFT){
        for(int v = 0;v < inLen / workLen;v++){//先将short输入转为float
            for(int i=0;i<workLen;i++){
                rInBuf[i]=float(inBuf[i+(workLen*v)]*winBuf[i]);
            }
            fftwf_execute(real_plan);
            if(frist){
                for(int i=1;i<fftLen+1;i++)
                    outBuf[i-1] = log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor;
                frist = false;
            }else{//累积
                for(int i=1;i<fftLen+1;i++)
                    outBuf[i-1] = outBuf[i] < log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor ?
                                outBuf[i] : log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor;
            }
        }
    }else if(disposeType == C2FFT){
        for(int v = 0;v < inLen / workLen;v++){
            for(int i=0;i<fftLen;++i){
                cInBuf[i][0]=float(inBuf[i*2+workLen*v]*winBuf[i]);
                cInBuf[i][1]=float(inBuf[i*2+1+workLen*v]*winBuf[i]);
            }
            fftwf_execute(real_plan);
            int halfLen = fftLen/2;
            if(frist){
                for(int i=0;i<halfLen;i++)
                    outBuf[i] = log10f(sqrtf(cOutBuf[i+halfLen][0]*cOutBuf[i+halfLen][0]+cOutBuf[i+halfLen][1]*cOutBuf[i+halfLen][1]))*20.0f + levelPoor;   //I
                for(int i=0;i<halfLen;i++)
                    outBuf[i+halfLen] = log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f+ levelPoor; //Q
                frist = false;
            }else{  //累积
                for(int i=0;i<fftLen/2;i++)
                    outBuf[i] = outBuf[i] < log10f(sqrtf(cOutBuf[i+halfLen][0]*cOutBuf[i+halfLen][0]+cOutBuf[i+halfLen][1]*cOutBuf[i+halfLen][1]))*20.0f + levelPoor ?
                                outBuf[i] : log10f(sqrtf(cOutBuf[i+halfLen][0]*cOutBuf[i+halfLen][0]+cOutBuf[i+halfLen][1]*cOutBuf[i+halfLen][1]))*20.0f + levelPoor;
                for(int i=0;i<fftLen/2;i++)
                    outBuf[i+fftLen/2] = outBuf[i+fftLen/2] < log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor ?
                                outBuf[i+fftLen/2] : log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor;
            }
        }
    }
    if(smooth){
        for(int j=0;j<smoothNum;j++)
            for(int i=1;i<fftLen;i++)
                outBuf[i]=(outBuf[i]+outBuf[i-1]*0.5+outBuf[i+1]*0.5)/2.0;
    }
}

void Spectrum::ConversionMAX(float inBuf[], int inLen, short outBuf[], short levelPoor, bool smooth, int smoothNum)
{
    bool frist = true;
    if(disposeType == R2FFT){
        for(int v = 0;v < inLen / workLen;v++){//先将short输入转为float
            for(int i=0;i<workLen;i++){
                rInBuf[i]=float(inBuf[(workLen*v) + i]*winBuf[i]);
            }
            fftwf_execute(real_plan);
            if(frist){
                for(int i=1;i<fftLen+1;++i)
                    outBuf[i-1] = log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor;
                frist = false;
            }else{//累积
                for(int i=1;i<fftLen+1;i++)
                    outBuf[i-1] = outBuf[i] > log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor ?
                                outBuf[i] : log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor;
            }
        }
    }else if(disposeType == C2FFT){
        for(int v = 0;v < inLen / workLen;v++){
            for(int i=0;i<fftLen;++i){
                cInBuf[i][0]=float(inBuf[i*2+workLen*v]*winBuf[i]);
                cInBuf[i][1]=float(inBuf[i*2+1+workLen*v]*winBuf[i]);
            }
            fftwf_execute(real_plan);
            int halfLen = fftLen/2;
            if(frist){
                for(int i=0;i<halfLen;i++)
                    outBuf[i] = log10f(sqrtf(cOutBuf[i+halfLen][0]*cOutBuf[i+halfLen][0]+cOutBuf[i+halfLen][1]*cOutBuf[i+halfLen][1]))*20.0f + levelPoor;   //I
                for(int i=0;i<halfLen;i++)
                    outBuf[i+halfLen] = log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f+ levelPoor; //Q
                frist = false;
            }else{  //累积
                for(int i=0;i<fftLen/2;i++)
                    outBuf[i] = outBuf[i] > log10f(sqrtf(cOutBuf[i+halfLen][0]*cOutBuf[i+halfLen][0]+cOutBuf[i+halfLen][1]*cOutBuf[i+halfLen][1]))*20.0f + levelPoor ?
                                outBuf[i] : log10f(sqrtf(cOutBuf[i+halfLen][0]*cOutBuf[i+halfLen][0]+cOutBuf[i+halfLen][1]*cOutBuf[i+halfLen][1]))*20.0f + levelPoor;
                for(int i=0;i<fftLen/2;i++)
                    outBuf[i+fftLen/2] = outBuf[i+fftLen/2] > log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor ?
                                outBuf[i+fftLen/2] : log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor;
            }
        }
    }
    if(smooth){
        for(int j=0;j<smoothNum;j++){
            for(int i=1;i<fftLen-1;i++)
                outBuf[i]=(outBuf[i]+outBuf[i-1]*0.5f+outBuf[i+1]*0.5f)/2.0f;
            outBuf[0] =  outBuf[1];
            outBuf[fftLen-1] = outBuf[fftLen-2];
        }
    }
}

void Spectrum::ConversionMAX(float inBuf[], int inLen, float outBuf[], short levelPoor, bool smooth, int smoothNum)
{
    bool frist = true;
    if(disposeType == R2FFT){
        for(int v = 0;v < inLen / workLen;v++){//先将short输入转为float
            for(int i=0;i<workLen;i++){
                rInBuf[i]=float(inBuf[(workLen*v) + i]*winBuf[i]);
            }
            fftwf_execute(real_plan);
            if(frist){
                for(int i=1;i<fftLen+1;++i)
                    outBuf[i-1] = log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor;
                frist = false;
            }else{//累积
                for(int i=1;i<fftLen+1;i++)
                    outBuf[i-1] = outBuf[i] > log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor ?
                                outBuf[i] : log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor;
            }
        }
    }else if(disposeType == C2FFT){
        for(int v = 0;v < inLen / workLen;v++){
            for(int i=0;i<fftLen;++i){
                cInBuf[i][0]=float(inBuf[i*2+workLen*v]*winBuf[i]);
                cInBuf[i][1]=float(inBuf[i*2+1+workLen*v]*winBuf[i]);
            }
            fftwf_execute(real_plan);
            int halfLen = fftLen/2;
            if(frist){
                for(int i=0;i<halfLen;i++)
                    outBuf[i] = log10f(sqrtf(cOutBuf[i+halfLen][0]*cOutBuf[i+halfLen][0]+cOutBuf[i+halfLen][1]*cOutBuf[i+halfLen][1]))*20.0f + levelPoor;   //I
                for(int i=0;i<halfLen;i++)
                    outBuf[i+halfLen] = log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f+ levelPoor; //Q
                frist = false;
            }else{  //累积
                for(int i=0;i<fftLen/2;i++)
                    outBuf[i] = outBuf[i] > log10f(sqrtf(cOutBuf[i+halfLen][0]*cOutBuf[i+halfLen][0]+cOutBuf[i+halfLen][1]*cOutBuf[i+halfLen][1]))*20.0f + levelPoor ?
                                outBuf[i] : log10f(sqrtf(cOutBuf[i+halfLen][0]*cOutBuf[i+halfLen][0]+cOutBuf[i+halfLen][1]*cOutBuf[i+halfLen][1]))*20.0f + levelPoor;
                for(int i=0;i<fftLen/2;i++)
                    outBuf[i+fftLen/2] = outBuf[i+fftLen/2] > log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor ?
                                outBuf[i+fftLen/2] : log10f(sqrtf(cOutBuf[i][0]*cOutBuf[i][0]+cOutBuf[i][1]*cOutBuf[i][1]))*20.0f + levelPoor;
            }
        }
    }
    if(smooth){
        for(int j=0;j<smoothNum;j++){
            for(int i=1;i<fftLen-1;i++)
                outBuf[i]=(outBuf[i]+outBuf[i-1]*0.5f+outBuf[i+1]*0.5f)/2.0f;
            outBuf[0] =  outBuf[1];
            outBuf[fftLen-1] = outBuf[fftLen-2];
        }
    }
}




